<template>
  <!-- 网络状态提示 -->
  <n-flex
    v-if="!networkStatus.isOnline.value"
    align="center"
    justify="center"
    class="z-999 absolute w-full h-40px rounded-4px text-(12px [--danger-text]) bg-[--danger-bg]">
    <svg class="size-16px">
      <use href="#cloudError"></use>
    </svg>
    当前网络不可用，请检查你的网络设置
  </n-flex>

  <Transition name="chat-init" appear mode="out-in" @after-leave="handleTransitionComplete">
    <!-- 初次加载的骨架屏 -->
    <!--    <n-flex-->
    <!--      v-if="messageOptions?.isLoading && !messageOptions?.cursor"-->
    <!--      vertical-->
    <!--      :size="18"-->
    <!--      :style="{ 'max-height': `calc(100vh - ${announcementHeight}px)` }"-->
    <!--      class="relative h-100vh box-border p-20px">-->
    <!--      <n-flex justify="end">-->
    <!--        <n-skeleton style="border-radius: 14px" height="40px" width="46%" :sharp="false" />-->
    <!--        <n-skeleton height="40px" circle />-->
    <!--      </n-flex>-->

    <!--      <n-flex>-->
    <!--        <n-skeleton height="40px" circle />-->
    <!--        <n-skeleton style="border-radius: 14px" height="60px" width="58%" :sharp="false" />-->
    <!--      </n-flex>-->

    <!--      <n-flex>-->
    <!--        <n-skeleton height="40px" circle />-->
    <!--        <n-skeleton style="border-radius: 14px" height="40px" width="26%" :sharp="false" />-->
    <!--      </n-flex>-->

    <!--      <n-flex justify="end">-->
    <!--        <n-skeleton style="border-radius: 14px" height="40px" width="60%" :sharp="false" />-->
    <!--        <n-skeleton height="40px" circle />-->
    <!--      </n-flex>-->
    <!--    </n-flex>-->

    <!-- 聊天内容 -->
    <VirtualList
      id="image-chat-main"
      ref="virtualListInst"
      :items="messageList"
      :buffer="5"
      :is-loading-more="isLoadingMore"
      @scroll="handleScroll"
      @scroll-direction-change="handleScrollDirectionChange"
      @load-more="handleLoadMore"
      class="scrollbar-container"
      :class="{ 'hide-scrollbar': !showScrollbar }"
      :style="{ 'max-height': `calc(100vh - 260px)` }"
      @mouseenter="showScrollbar = true"
      @mouseleave="showScrollbar = false">
      <template #default="{ item, index }">
        <n-flex
          vertical
          :key="index"
          class="flex-y-center"
          :class="[
            item.type === 'TextPayload' ? 'min-h-22px' : 'min-h-62px',
            isGroup ? 'p-[14px_10px_14px_20px]' : 'chat-single p-[4px_10px_10px_20px]'
          ]">
          <!-- 信息间隔时间 -->
          <span v-if="item.type !== TencentCloudChat.TYPES.MSG_CUSTOM" class="text-(12px #909090) select-none p-4px">
            {{ formatTimestamp(item.time) }}
          </span>

          <!--  消息为撤回消息  -->
          <div v-if="item.isRevoked">
            <template v-if="isGroup">
              <n-flex align="center" :size="6">
                <p class="text-(12px #909090) select-none cursor-default">你撤回了一条消息</p>
                <p class="text-(12px #13987f) select-none cursor-pointer" @click="void 0">重新编辑</p>
              </n-flex>
              <span class="text-12px color-#909090 select-none" v-html="'撤回消息'"></span>
            </template>
            <template v-else>
              <n-flex align="center" :size="6">
                <p class="text-(12px #909090) select-none cursor-default">'你撤回了一条消息'</p>
                <p class="text-(12px #13987f) select-none cursor-pointer" @click="void 0">重新编辑</p>
              </n-flex>
            </template>
          </div>

          <!-- 消息为系统消息时 -->
          <div v-else-if="item.type === TencentCloudChat.TYPES.MSG_GRP_SYS_NOTICE">
            <p class="text-(12px #909090) select-none cursor-default">系统消息</p>
          </div>
          <div v-else-if="item.type === TencentCloudChat.TYPES.MSG_GRP_TIP">
            <p class="text-(12px #909090) select-none cursor-default" v-html="getTipMessage(item)"></p>
          </div>
          <div v-else-if="item.type === TencentCloudChat.TYPES.MSG_CUSTOM">
            <!--            <p class="text-(12px #909090) select-none cursor-default">-->
            <!--              <span class="text-blue-4">{{ item.from }}</span> : {{ JSON.parse(item.payload.data).content }}-->
            <!--            </p>-->
          </div>

          <!-- 好友或者群聊的信息 -->
          <div
            v-else
            class="flex flex-col w-full"
            :class="[{ 'items-end': item.from === myProfile.userID }, isGroup ? 'gap-18px' : 'gap-2px']">
            <!-- 信息时间(单聊) -->
            <div
              v-if="!isGroup"
              class="text-(12px #909090) h-12px w-fit select-none pr-68px"
              :class="item.from === myProfile.userID ? 'pr-42px' : 'pl-42px'">
              <Transition name="fade-single">
                <span v-if="hoverBubble.key === item.ID">
                  {{ formatTimestamp(item.time, true) }}
                </span>
              </Transition>
            </div>
            <div class="flex items-start flex-1" :class="item.from === myProfile.userID ? 'flex-row-reverse' : ''">
              <!-- 头像 -->
              <n-popover
                :ref="(el) => (infoPopoverRefs[item.from] = el)"
                @update:show="handlePopoverUpdate(item.from, $event)"
                trigger="click"
                placement="right"
                :show-arrow="false"
                style="padding: 0; background: var(--bg-info)">
                <template #trigger>
                  <ContextMenu
                    @select="$event.click(item, 'Main')"
                    :content="item"
                    :menu="isGroup ? optionsList : void 0"
                    :special-menu="report">
                    <!-- 存在头像时候显示 -->
                    <n-avatar
                      round
                      :size="34"
                      @click="selectKey = item.from"
                      class="select-none"
                      :src="item.avatar"
                      fallback-src="/logo.png"
                      :class="item.from === myProfile.userID ? '' : 'mr-10px'" />
                  </ContextMenu>
                </template>
                <!-- 用户个人信息框 -->
                <InfoPopover v-if="selectKey === item.from" :uid="item.from" />
              </n-popover>
              <n-flex
                vertical
                justify="center"
                :size="6"
                class="color-[--text-color] flex-1"
                :class="item.from === myProfile.userID ? 'items-end mr-10px' : ''">
                <n-flex
                  :size="6"
                  align="center"
                  :style="item.from === myProfile.userID ? 'flex-direction: row-reverse' : ''">
                  <ContextMenu
                    @select="$event.click(item, 'Main')"
                    :content="item"
                    :menu="isGroup ? optionsList : void 0"
                    :special-menu="report">
                    <n-flex
                      :size="6"
                      class="select-none"
                      align="center"
                      v-if="isGroup"
                      :style="item.from === myProfile.userID ? 'flex-direction: row-reverse' : ''">
                      <!-- 用户名 -->
                      <span class="text-12px select-none color-#909090 inline-block align-top">
                        {{ getCompanyAndDepartment(item) }}
                      </span>
                    </n-flex>
                  </ContextMenu>
                  <!-- 群主 -->
                  <div
                    v-if="isGroup && isOwner(item.from)"
                    class="flex px-4px py-3px rounded-4px bg-#d5304f30 size-fit select-none">
                    <span class="text-(9px #d5304f)">群主</span>
                  </div>
                  <!-- 管理员 -->
                  <div
                    v-if="isGroup && isAdmin(item.from)"
                    class="flex px-4px py-3px rounded-4px bg-#1a7d6b30 size-fit select-none">
                    <span class="text-(9px #1a7d6b)">管理员</span>
                  </div>
                  <!-- 信息时间(群聊) -->
                  <Transition name="fade-group">
                    <span v-if="isGroup && hoverBubble.key === item.ID" class="text-(12px #909090) select-none">
                      {{ formatTimestamp(item.time, true) }}
                    </span>
                  </Transition>
                </n-flex>
                <!--  气泡样式  -->
                <ContextMenu
                  :content="item"
                  @contextmenu="handleMacSelect"
                  @mouseenter="handleMouseEnter(item.ID)"
                  @mouseleave="handleMouseLeave"
                  class="w-fit relative flex flex-col"
                  :data-key="item.from === myProfile.userID ? `U${item.ID}` : `Q${item.ID}`"
                  :class="item.from === myProfile.userID ? 'items-end' : 'items-start'"
                  :style="{ '--bubble-max-width': isGroup ? '32vw' : '50vw' }"
                  @select="$event.click(item)"
                  :menu="handleItemType(item.type)"
                  :emoji="emojiList"
                  :special-menu="specialMenuList"
                  @click="handleMsgClick(item)">
                  <!-- 渲染消息内容体 TODO: 等完善消息类型后逐渐替换使用RenderMessage -->
                  <RenderMessage
                    :class="[
                      '!select-auto !cursor-text',
                      { active: activeBubble === item.ID && !isSpecialMsgType(item.type) },
                      !isSpecialMsgType(item.type) ? (item.from === myProfile.userID ? 'bubble-oneself' : 'bubble') : ''
                    ]"
                    :message="item" />

                  <!--  消息为为图片类型(不固定宽度和高度), 多张图片时渲染  -->
                  <!-- <n-image-group v-if="Array.isArray(item.message.body.url) && item.message.type === MsgEnum.IMAGE">
                    <n-flex class="photo-wall" vertical>
                      <n-image
                        class="select-none"
                        v-for="(src, index) in item.message.body.url"
                        :key="index"
                        :img-props="{ style: { maxWidth: '325px', maxHeight: '165px', width: '100%', height: 'auto' } }"
                        show-toolbar-tooltip
                        style="border-radius: 8px"
                        :fallback-src="'https://07akioni.oss-cn-beijing.aliyuncs.com/07akioni.jpeg'"
                        :src="src"></n-image>
                    </n-flex>
                  </n-image-group> -->

                  <!-- 消息为文件 -->
                  <div
                    v-if="item.type === TencentCloudChat.TYPES.MSG_FILE"
                    style="width: 180px; height: 50px"
                    class="cursor-pointer border hover:bg-[#f7f7f7] p-3">
                    <n-space justify="space-between">
                      <n-space vertical style="width: 130px; font-size: 13px">
                        <n-performant-ellipsis style="font-size: 14px">{{
                          item.payload.fileName
                        }}</n-performant-ellipsis>
                        <span class="color-gray">{{ formatFileSize(item.payload.fileSize) }}</span>
                      </n-space>
                      <n-flex style="width: 30px" justify="center" align="center">
                        <n-image
                          class="select-none"
                          show-toolbar-tooltip
                          preview-disabled
                          style="border-radius: 8px"
                          :alt="item.payload.fileName"
                          :src="`/file/${getFileExt(item.payload.fileName)}.svg`"></n-image>
                      </n-flex>
                    </n-space>
                  </div>
                  <div
                    v-if="item.type === TencentCloudChat.TYPES.MSG_VIDEO"
                    style="max-width: 325px; max-height: 165px; border-radius: 8px">
                    <video
                      controls
                      :src="item.payload.videoUrl"
                      :poster="item.payload.thumbUrl"
                      style="max-width: 325px; max-height: 165px">
                      不支持视频播放
                    </video>
                  </div>
                  <!-- 消息状态指示器 -->
                  <div v-if="item.from === myProfile.userID" class="absolute -left-10 bottom-2">
                    <span
                      v-if="activeItem?.type === TencentCloudChat.TYPES.CONV_C2C"
                      class="text-gray-400 text-size-sm"
                      >{{ item.isRead ? '已读' : '未读' }}</span
                    >
                    <n-icon v-if="item.status === 'fail'" class="text-#d5304f cursor-pointer" @click.stop="void item">
                      <svg class="size-16px">
                        <use href="#cloudError"></use>
                      </svg>
                    </n-icon>
                  </div>
                </ContextMenu>

                <!-- 回复的内容 -->
                <!--                <n-flex-->
                <!--                  align="center"-->
                <!--                  :size="6"-->
                <!--                  v-if="item.cloudCustomData"-->
                <!--                  @click="void item.reply"-->
                <!--                  class="reply-bubble relative w-fit custom-shadow">-->
                <!--                  <svg class="size-14px">-->
                <!--                    <use href="#to-top"></use>-->
                <!--                  </svg>-->
                <!--                  <span>{{ `${item.cloudCustomData.messageSender}: ` }}</span>-->
                <!--                  <span v-if="item.cloudCustomData.messageReply.messageType === 0" class="content-span">-->
                <!--                    {{ item.cloudCustomData.messageAbstract.summary }}-->
                <!--                  </span>-->
                <!--                  <div v-if="item.cloudCustomData.messageReply.messageType === 1" class="reply-img-sub">-->
                <!--                    {{ item.cloudCustomData.messageAbstract.summary }}-->
                <!--                  </div>-->
                <!--                </n-flex>-->
              </n-flex>
            </div>
          </div>
        </n-flex>
      </template>
    </VirtualList>
  </Transition>

  <!-- 弹出框 -->
  <n-modal v-model:show="modalShow" class="w-350px border-rd-8px">
    <div class="bg-[--bg-popover] w-360px h-full p-6px box-border flex flex-col">
      <div
        v-if="type() === 'macos'"
        @click="modalShow = false"
        class="mac-close z-999 size-13px shadow-inner bg-#ed6a5eff rounded-50% select-none absolute left-6px">
        <svg class="hidden size-7px color-#000 font-bold select-none absolute top-3px left-3px">
          <use href="#close"></use>
        </svg>
      </div>

      <svg v-if="type() === 'windows'" @click="modalShow = false" class="w-12px h-12px ml-a cursor-pointer select-none">
        <use href="#close"></use>
      </svg>
      <div class="flex flex-col gap-30px p-[22px_10px_10px_22px] select-none">
        <span class="text-14px">提示内容</span>

        <n-flex justify="end">
          <n-button @click="void 0" class="w-78px" color="#13987f">确定</n-button>
          <n-button @click="modalShow = false" class="w-78px" secondary>取消</n-button>
        </n-flex>
      </div>
    </div>
  </n-modal>

  <!--  悬浮按钮提示(底部悬浮) -->
  <footer
    class="float-footer"
    v-if="shouldShowFloatFooter && currentConvUnreadCount > 0"
    :class="isGroup ? 'right-220px' : 'right-50px'">
    <div class="float-box" :class="{ max: currentConvUnreadCount > 99 }" @click="scrollToBottom">
      <n-flex justify="space-between" align="center">
        <n-icon :color="currentConvUnreadCount > 99 ? '#ce304f' : '#13987f'">
          <svg>
            <use href="#double-down"></use>
          </svg>
        </n-icon>
        <span
          v-if="currentConvUnreadCount > 0"
          class="text-12px"
          :class="{ 'color-#ce304f': currentConvUnreadCount > 99 }">
          {{ currentConvUnreadCount > 99 ? '99+' : currentConvUnreadCount }}条新消息
        </span>
      </n-flex>
    </div>
  </footer>
</template>
<script setup lang="ts">
import { useNetworkStatus } from '@/hooks/useNetworkStatus'
import { formatTimestamp } from '@/utils/ComputedTime.ts'
import { useChatMain } from '@/hooks/useChatMain.ts'
import TencentCloudChat, { Conversation, Message } from '@tencentcloud/chat'
import { useTencentConversationStore } from '@/stores/tencentConversationStore.ts'
import { useTencentMessageStore } from '@/stores/tencentMessageStore.ts'
import { useTencentUserStore } from '@/stores/tencentUserStore.ts'
import { useTencentGroupStore } from '@/stores/tencentGroupStore.ts'
import { useDebounceFn } from '@vueuse/core'
import { type } from '@tauri-apps/plugin-os'
import { VirtualListExpose } from '@/components/common/VirtualList.vue'
import { usePopover } from '@/hooks/usePopover.ts'
import { useMitt } from '@/hooks/useMitt.ts'
import { MittEnum } from '@/enums'
import { delay } from 'lodash-es'
import { useMiaoxinCompanyStore } from '@/stores/miaoxinCompanyStore.ts'

const { activeItem } = defineProps<{
  activeItem: Conversation
}>()
/** 鼠标悬浮的气泡显示对应的时间 */
const hoverBubble = ref<{
  key: number
  timer?: NodeJS.Timeout
}>({
  key: -1
})
const miaoxinCompanyStore = useMiaoxinCompanyStore()
const tencentConversationStore = useTencentConversationStore()
const tencentGroupStore = useTencentGroupStore()
const tencentUserStore = useTencentUserStore()
const { myProfile } = storeToRefs(tencentUserStore)
const tencentMessageStore = useTencentMessageStore()
const networkStatus = useNetworkStatus()
const modalShow = ref(false)
const showScrollbar = ref(false)
const isGroup = computed(() => activeItem?.type === TencentCloudChat.TYPES.CONV_GROUP)
const currentConvUnreadCount = computed(() => tencentConversationStore.currentConv.unreadCount || 0)

// 记录当前滚动位置相关信息
const isAutoScrolling = ref(false)

/** 记录是否正在向上滚动 */
const isScrollingUp = ref(false)
/** 记录是否正在向下滚动 */
const isScrollingDown = ref(false)
/** 虚拟列表 */
const virtualListInst = useTemplateRef<VirtualListExpose>('virtualListInst')
// 记录 requestAnimationFrame 的返回值
const rafId = ref<number>()
// 缓存消息ID到索引的映射，提高查找效率
const messageIdToIndexMap = ref(new Map<string, number>())
// 添加标记，用于识别是否正在加载历史消息
const isLoadingMore = ref(false)
/** List中的Popover组件实例 */
const infoPopoverRefs = ref<Record<string, any>>([])
/** 记录右键菜单时选中的气泡的元素(用于处理mac右键会选中文本的问题) */
const recordEL = ref()
const isMac = computed(() => type() === 'macos')

const {
  emojiList,
  scrollTop,
  selectKey,
  activeBubble,
  optionsList,
  specialMenuList,
  report,
  handleItemType,
  handleMsgClick
} = useChatMain()
const { handlePopoverUpdate, enableScroll } = usePopover(selectKey, 'image-chat-main')
provide('popoverControls', { enableScroll })

const isOwner = (userID: string) => {
  return userID === tencentGroupStore.ownerID
}

const isAdmin = (userID: string) => {
  const user = tencentGroupStore.groupAdminMap[tencentGroupStore.currentGroup.groupID!]
  return user && user[userID] && user[userID].role === TencentCloudChat.TYPES.GRP_MBR_ROLE_ADMIN
}

const messageList = computed(() => {
  return tencentMessageStore.messageListMap[activeItem.conversationID]
})

// 更新消息索引映射
const updateMessageIndexMap = () => {
  messageIdToIndexMap.value.clear()
  messageList.value.forEach((msg, index) => {
    messageIdToIndexMap.value.set(msg.ID, index)
  })
}

watch(
  messageList,
  (newVal, oldVal) => {
    if (!newVal.length) return

    updateMessageIndexMap()

    // if (newVal.length < 10) {
    //   if (!oldVal.length) {
    //     scrollToBottom()
    //   }
    //
    //   if (!tencentMessageStore.isCompleted && !tencentMessageStore.isLoading) {
    //     tencentMessageStore.getMessageList({ conversationID: tencentConversationStore.currentConv.conversationID })
    //     return
    //   }
    // }

    console.log('message list', newVal.length, oldVal.length, scrollTop.value)
    if (newVal.length > oldVal.length) {
      const latestMessage = newVal[newVal.length - 1]
      if (scrollTop.value < 26) {
        console.log('watch message list', newVal.length, oldVal.length)
        requestAnimationFrame(() => {
          virtualListInst.value?.scrollTo({ index: newVal.length - oldVal.length })
        })
      }

      if (latestMessage.from === myProfile.value.userID) {
        scrollToBottom()
        return
      }

      const container = virtualListInst.value?.getContainer()
      if (container) {
        const distanceFromBottom = container.scrollHeight - container.scrollTop - container.clientHeight
        console.log('distance from bottom', distanceFromBottom)
        if (distanceFromBottom <= 300) {
          scrollToBottom()
          return
        }

        if (latestMessage.from !== myProfile.value.userID) {
          // TODO
        }
      }
    }
  },
  {
    deep: true
  }
)

watch(
  () => activeItem,
  async (newVal, oldVal) => {
    if (!oldVal || oldVal.conversationID !== newVal.conversationID) {
      // messageList.value = []
      console.log('会话变更', newVal)
      await nextTick(() => {
        scrollToBottom()
      })
    }
  },
  {
    immediate: true
  }
)

// 滚动到底部
const scrollToBottom = () => {
  if (!virtualListInst.value) return
  virtualListInst.value?.scrollTo({ position: 'bottom', behavior: 'instant' })
}

// 是否显示悬浮页脚
const shouldShowFloatFooter = computed(() => {
  const container = virtualListInst.value?.getContainer()
  if (!container) return false

  const scrollHeight = container.scrollHeight
  const clientHeight = container.clientHeight
  const distanceFromBottom = scrollHeight - scrollTop.value - clientHeight

  // 只在向下滚动时显示按钮
  if (!isScrollingDown.value) {
    return false
  }

  // 当距离底部超过一个屏幕高度时显示向下箭头
  return distanceFromBottom > clientHeight
})

const getFileExt = (fileName: string) => {
  return fileName.split('.').pop()?.toLowerCase()
}

const formatFileSize = (fileSize: number) => {
  const baseSize = 1024
  if (fileSize < baseSize) {
    return fileSize + ' bit'
  }

  if (fileSize < baseSize * baseSize) {
    return (fileSize / baseSize).toFixed(1) + ' kb'
  }

  if (fileSize < baseSize * baseSize * baseSize) {
    return (fileSize / (baseSize * baseSize)).toFixed(1) + ' mb'
  }

  return ''
}

const isSpecialMsgType = (type: TencentCloudChat.TYPES) => {
  return type !== TencentCloudChat.TYPES.MSG_TEXT
}

const getCompanyAndDepartment = (item: Message) => {
  const profile = miaoxinCompanyStore.getOrganizationUserProfileById(item.from)
  return `${item.nameCard || item.nick} (${profile?.CompanyNickName}-${profile?.DepartmentName})`
}

const editOptions = [
  { label: '群名称', value: 'groupName' },
  { label: '群头像', value: 'avatar' },
  { label: '简介', value: 'introduction' },
  { label: '群公告', value: 'notification' },
  { label: '最大用户数量', value: 'maxMemberNum' },
  { label: '全体禁言', value: 'muteAllMembers' },
  { label: '入群方式', value: 'joinOption' },
  { label: '邀请方式', value: 'inviteOption' },
  { label: '自定义字段', value: 'groupCustomField' }
]

const getTipMessage = (message: Message) => {
  let userIDS = ''
  message.payload.userIDList.forEach((item: any) => {
    userIDS += `<span class="text-blue-4">${item}</span> `
  })
  // userIDS.splice(0, -1)

  let msg = `<span class="text-blue-4">${message.payload.operatorInfo.nick}</span> 将 ` + userIDS
  switch (message.payload.operationType) {
    case TencentCloudChat.TYPES.GRP_TIP_MBR_JOIN:
      msg = userIDS + ' 加入群聊'
      break

    case TencentCloudChat.TYPES.GRP_TIP_MBR_QUIT:
      msg = userIDS + ' 已退出群聊'
      break

    case TencentCloudChat.TYPES.GRP_TIP_MBR_KICKED_OUT:
      msg += ' 踢出群聊'
      break

    case TencentCloudChat.TYPES.GRP_TIP_MBR_SET_ADMIN:
      msg = `<span class="text-blue-4">${message.payload.operatorInfo.nick}</span> 将 ${message.nick} 设为管理员`
      break

    case TencentCloudChat.TYPES.GRP_TIP_MBR_CANCELED_ADMIN:
      msg = `<span class="text-blue-4">${message.payload.operatorInfo.nick}</span> 将 ${message.nick} 撤销管理员`
      break

    case TencentCloudChat.TYPES.GRP_TIP_GRP_PROFILE_UPDATED:
      let option = { label: '', value: '' }
      editOptions.forEach((item) => {
        if (message.payload.newGroupProfile.hasOwnProperty(item.value)) {
          option = item
        }
      })
      msg = option
        ? `<span class="text-blue-4">${message.payload.operatorInfo.nick}</span> 修改 ${option.label} : ${message.payload.newGroupProfile[option.value]}`
        : ''
      break

    case TencentCloudChat.TYPES.GRP_TIP_MBR_PROFILE_UPDATED:
      msg = userIDS + ' 更新了个人资料'
      break

    default:
      msg = '群通知'
  }

  return msg
}

// 处理加载更多
const handleLoadMore = async () => {
  // 如果信息已经加载完成 || 正在加载
  if (tencentMessageStore.isCompleted || tencentMessageStore.isLoading || isLoadingMore.value) return

  // 记录当前的内容高度
  const container = virtualListInst.value?.getContainer()
  if (!container) return
  const oldScrollHeight = container.scrollHeight
  console.log('old scroll height', oldScrollHeight)

  isLoadingMore.value = true

  // 使用CSS变量控制滚动行为，避免直接操作DOM样式
  container.classList.add('loading-history')

  try {
    tencentMessageStore.getMessageList({ conversationID: activeItem.conversationID })

    // 加载完成后，计算新增内容的高度差，并设置滚动位置
    await nextTick(() => {
      const c = virtualListInst.value?.getContainer()
      const ns = c?.scrollHeight
      console.log(c?.scrollTop, ns, c?.offsetTop, c?.offsetHeight)
    })
    // const newScrollHeight = container.scrollHeight
    // const heightDiff = newScrollHeight - oldScrollHeight
    // console.log('height diff', newScrollHeight, heightDiff, container.offsetHeight)
    // if (heightDiff > 0) {
    //   container.scrollTop = heightDiff
    // }
    container.scrollTop = container.offsetHeight

    updateMessageIndexMap()
  } catch (error) {
    console.error('加载历史消息失败:', error)
  } finally {
    // 恢复滚动交互
    setTimeout(() => {
      container.classList.remove('loading-history')
      isLoadingMore.value = false
    }, 100)
  }
}

// 处理滚动事件(用于页脚显示功能)
const handleScroll = () => {
  if (isAutoScrolling.value) return // 如果是自动滚动，不处理
  const container = virtualListInst.value?.getContainer()
  if (!container) return

  // 获取已滚动的距离
  scrollTop.value = container.scrollTop
  // 获取整个滚动容器的高度
  const scrollHeight = container.scrollHeight
  // 获取容器的可视区域高度
  const clientHeight = container.clientHeight
  // 计算距离底部的距离
  const distanceFromBottom = scrollHeight - scrollTop.value - clientHeight

  // 存储 requestAnimationFrame 的返回值
  if (rafId.value) {
    cancelAnimationFrame(rafId.value)
  }

  rafId.value = requestAnimationFrame(async () => {
    // 处理触顶加载更多
    if (scrollTop.value < 26) {
      if (tencentMessageStore.isLoading || isLoadingMore.value) return
      await handleLoadMore()
    }

    // 处理底部滚动和新消息提示
    if (distanceFromBottom <= 20 && currentConvUnreadCount.value > 0) {
      tencentConversationStore.setMessageRead(activeItem.conversationID)
    }
  })
}

// 添加防抖的鼠标事件处理
const debouncedMouseEnter = useDebounceFn((key: any) => {
  hoverBubble.value.key = key
}, 300)

// 当鼠标进入时触发的处理函数
const handleMouseEnter = (key: any) => {
  // 清除之前的定时器
  if (hoverBubble.value.timer) {
    clearTimeout(hoverBubble.value.timer)
  }
  // 设置新的定时器
  hoverBubble.value.timer = setTimeout(() => {
    debouncedMouseEnter(key)
  }, 800)
}

// 当鼠标离开时触发的处理函数
const handleMouseLeave = () => {
  // 如果定时器存在，则清除定时器并重置为undefined
  if (hoverBubble.value.timer) {
    clearTimeout(hoverBubble.value.timer)
    hoverBubble.value.timer = void 0
  }
  // 重置悬浮气泡的key值为-1
  hoverBubble.value.key = -1
}

// 处理过渡动画完成后的滚动
const handleTransitionComplete = () => {
  nextTick(() => {
    scrollToBottom()
  })
}

// 处理滚动方向变化
const handleScrollDirectionChange = (direction: 'up' | 'down') => {
  isScrollingUp.value = direction === 'up'
  isScrollingDown.value = direction === 'down'
}

// 解决mac右键会选中文本的问题
const handleMacSelect = (event: any) => {
  if (isMac.value) {
    event.target.classList.add('select-none')
    recordEL.value = event.target
  }
}

const closeMenu = (event: any) => {
  if (!event.target.matches('.bubble', 'bubble-oneself')) {
    activeBubble.value = ''
    // 解决mac右键会选中文本的问题
    if (isMac.value && recordEL.value) {
      recordEL.value.classList.remove('select-none')
    }
  }
  if (!event.target.matches('.active-reply')) {
    /** 解决更替交换回复气泡时候没有触发动画的问题 */
    if (!event.target.matches('.reply-bubble *')) {
      nextTick(() => {
        const activeReplyElement = document.querySelector('.active-reply') as HTMLElement
        if (activeReplyElement) {
          activeReplyElement.classList.add('reply-exit')
          delay(() => {
            activeReplyElement.classList.remove('reply-exit')
            // activeReply.value = ''
          }, 300)
        }
      })
    }
  }
}

// 给气泡添加动画
const addToDomUpdateQueue = (index: string, id: string) => {
  // 使用 nextTick 确保虚拟列表渲染完最新的项目后进行滚动
  nextTick(() => {
    /** data-key标识的气泡,添加前缀用于区分用户消息，不然气泡动画会被覆盖 */
    const dataKey = id === myProfile.value.userID ? `U${index}` : `Q${index}`
    const lastMessageElement = document.querySelector(`[data-key="${dataKey}"]`) as HTMLElement
    if (lastMessageElement) {
      console.log('触发气泡添加动画')
      // 添加动画类
      lastMessageElement.classList.add('bubble-animation')
      // 监听动画结束事件
      const handleAnimationEnd = () => {
        lastMessageElement.classList.remove('bubble-animation')
        lastMessageElement.removeEventListener('animationend', handleAnimationEnd)
      }
      lastMessageElement.addEventListener('animationend', handleAnimationEnd)
    }
  })
}

onMounted(() => {
  nextTick(() => {
    scrollToBottom()
    updateMessageIndexMap()
  })

  useMitt.on(MittEnum.MESSAGE_ANIMATION, (message: Message) => {
    addToDomUpdateQueue(message.ID, message.from)
  })

  useMitt.on(`${MittEnum.INFO_POPOVER}-Main`, (event: any) => {
    selectKey.value = event.uid
    infoPopoverRefs.value[event.uid].setShow(true)
    handlePopoverUpdate(event.uid)
  })

  window.addEventListener('click', closeMenu, true)

  useMitt.on('MESSAGE_RECEIVED_UPDATED', async () => {
    await nextTick(() => {
      scrollToBottom()
    })
  })
})

onUnmounted(() => {
  if (rafId.value) {
    cancelAnimationFrame(rafId.value)
  }
  if (hoverBubble.value.timer) {
    clearTimeout(hoverBubble.value.timer)
    hoverBubble.value.timer = void 0
  }
  hoverBubble.value.key = -1

  window.removeEventListener('click', closeMenu, true)
})
</script>

<style scoped lang="scss">
@use '@/styles/scss/chat-main';
</style>
